package com.cn.lb.route;

import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.cn.lb.support.RibbonFilterContext;
import com.cn.lb.support.RibbonFilterContextHolder;
import com.cn.utils.SaplingConstant;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @author: chenyuncong
 * @Date: 2019/12/6 15:25
 */
public class NacosServerRule extends ZoneAvoidanceRule {
    @Autowired
    private ConfigurableEnvironment environment;

    @Override
    public Server choose(Object key) {
        ILoadBalancer lb = this.getLoadBalancer();
        if (lb == null) {
            return null;
        } else {
            NacosServer server = null;
            final RibbonFilterContext context = RibbonFilterContextHolder.getCurrentContext();
            while(server == null) {
                if (Thread.interrupted()) {
                    return null;
                }

                List<Server> upList = lb.getReachableServers();
                List<Server> allList = lb.getAllServers();
                int serverCount = allList.size();
                if (serverCount == 0) {
                    return null;
                }

                int index = this.chooseRandomInt(serverCount);
                server = (NacosServer)upList.get(index);
//                server
                if (server == null) {
                    Thread.yield();
                } else {
                    if (server.isAlive()) {

                        boolean signEnabled = false;
                        if(server.getMetadata().containsKey(SaplingConstant.SERVICE_ENABLED)){
                            signEnabled=server.getMetadata().get(SaplingConstant.SERVICE_ENABLED).equals(environment.getProperty(SaplingConstant.SERVICE_ENABLED).toString());
                        }
                        if(signEnabled){
                            boolean signVersion=false;
                            boolean signGroup=false;
                            if(server.getMetadata().containsKey(SaplingConstant.SERVICE_VERSION)){
                                signVersion=server.getMetadata().get(SaplingConstant.SERVICE_VERSION).equals(environment.getProperty(SaplingConstant.SERVICE_VERSION).toString());
                            }
                            if(server.getMetadata().containsKey(SaplingConstant.SERVICE_GROUP)){
                                signGroup=server.getMetadata().get(SaplingConstant.SERVICE_GROUP).equals(environment.getProperty(SaplingConstant.SERVICE_GROUP).toString());
                            }
                            if(signVersion&&signGroup){
                                return server;
                            }
                        }

//                        System.out.println(server.getMetadata().get("test"));
//                        return server;
                    }
                    server = null;
                    Thread.yield();
                }
            }

            return server;
        }

//        return null;
    }
    protected int chooseRandomInt(int serverCount) {
        return ThreadLocalRandom.current().nextInt(serverCount);
    }
}
